/* Processed by ecpg (4.2.1) */
/* These include files are added by the preprocessor */
#include <ecpgtype.h>
#include <ecpglib.h>
#include <ecpgerrno.h>
#include <sqlca.h>
/* End of automatic include section */

#line 1 "sqlwrite.ec"
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netdb.h>
#include <netinet/ether.h>
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <pthread.h>
#include <sys/time.h>
#include <unistd.h>
#include <syslog.h>

extern "C" {
#include <pcap.h>
}

#include <unistd.h>
#include <stdio.h>
#include <getopt.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>

#include <list>
#include <map>
#include <string>

using namespace std;


#include "ip.h"
#include "dns.h"
#include "prio.h"
#include "monlist.h"


#line 1 "/usr/include/postgresql/sqlca.h"
#ifndef POSTGRES_SQLCA_H
#define POSTGRES_SQLCA_H

#ifndef DLLIMPORT
#if  defined(WIN32) || defined(__CYGWIN__)
#define DLLIMPORT __declspec (dllimport)
#else
#define DLLIMPORT
#endif   /* __CYGWIN__ */
#endif   /* DLLIMPORT */

#define SQLERRMC_LEN	150

#ifdef __cplusplus
extern		"C"
{
#endif

struct sqlca_t
{
	char		sqlcaid[8];
	long		sqlabc;
	long		sqlcode;
	struct
	{
		int			sqlerrml;
		char		sqlerrmc[SQLERRMC_LEN];
	}			sqlerrm;
	char		sqlerrp[8];
	long		sqlerrd[6];
	/* Element 0: empty						*/
	/* 1: OID of processed tuple if applicable			*/
	/* 2: number of rows processed				*/
	/* after an INSERT, UPDATE or				*/
	/* DELETE statement					*/
	/* 3: empty						*/
	/* 4: empty						*/
	/* 5: empty						*/
	char		sqlwarn[8];
	/* Element 0: set to 'W' if at least one other is 'W'	*/
	/* 1: if 'W' at least one character string		*/
	/* value was truncated when it was			*/
	/* stored into a host variable.				*/

	/*
	 * 2: if 'W' a (hopefully) non-fatal notice occurred
	 */	/* 3: empty */
	/* 4: empty						*/
	/* 5: empty						*/
	/* 6: empty						*/
	/* 7: empty						*/

	char		sqlstate[5];
};

struct sqlca_t *ECPGget_sqlca(void);

#ifndef POSTGRES_ECPG_INTERNAL
#define sqlca (*ECPGget_sqlca())
#endif

#ifdef __cplusplus
}
#endif

#endif

#line 36 "sqlwrite.ec"


static pthread_mutex_t SqlWriteMutex;

void	SQLConnect(char *connectionInfo)
{
	/* exec sql begin declare section */
		
	
#line 43 "sqlwrite.ec"
 char * connection    ;
/* exec sql end declare section */
#line 44 "sqlwrite.ec"


	connection = connectionInfo;

	{ ECPGconnect(__LINE__, 0, connection , NULL,NULL , NULL, 0); }
#line 48 "sqlwrite.ec"

	if(sqlca.sqlcode) {
		cerr << "connect Error # " << sqlca.sqlerrm.sqlerrml << " '" << sqlca.sqlerrm.sqlerrmc << "'" << endl;
		exit(0);
	}
	pthread_mutex_init(&SqlWriteMutex, NULL);
}

static void timevalToDate(const struct timeval *in, char *out)
{
   struct tm *ti = localtime(&in->tv_sec);
	sprintf(out, "%04d-%02d-%02d %02d:%02d:%02d.%d", 
			ti->tm_year + 1900, ti->tm_mon + 1, ti->tm_mday,
			ti->tm_hour, ti->tm_min, ti->tm_sec,
			in->tv_usec);
}


static unsigned char *escBinary(const unsigned char *in, int inSize)
{
	unsigned char *out = 0;
	unsigned char *oret;
	const unsigned char *inp = in;
	int	outSize = 0;

	for  (int kk = 0; kk < 2; kk++) {
		if (kk == 1) {
			oret = out = new unsigned char[outSize];
			outSize = 0;
			in = inp;
		}
		for (int ii = 0; ii < inSize; ii++, in++) {
			switch (*in) {
			case '\0':
				outSize += 6;	// "\000"
				if (out) {
					memcpy(out, "\\\\000", 6);
					out += 6;
				}
				break;
			case '\'':
				outSize += 3;	// "\'"
				if (out) {
					memcpy(out, "\\\\'", 3);
					out += 3;
				}
				break;
			case '\\':
				outSize += 4;	// "\\"
				if (out) {
					memcpy(out, "\\\\\\\\", 4);
					out += 4;
				}
				break;
			default:
				if (out) 
					*out++ = *in;
				outSize++;
				break;
			}
		}
		if (out)
			*out++ = '\0';
		outSize++;
	}
	return oret;
}
bool	SQlSaveRecord(CRecord *cr, string interfaceName,  struct timeval *now)
{
	struct in_addr kk;
	bool retval = true;
	/* exec sql begin declare section */
		
		
		
	 	
		
	 	
		
		
		
		
	  
	 		
		
			
	 	
		
	
#line 120 "sqlwrite.ec"
 int  f_src_ip_serial    ;
 
#line 121 "sqlwrite.ec"
 int  f_dst_ip_serial    ;
 
#line 122 "sqlwrite.ec"
 int  f_port_src    ;
 
#line 123 "sqlwrite.ec"
 int  f_port_dst    ;
 
#line 124 "sqlwrite.ec"
 int  f_protocol_number    ;
 
#line 125 "sqlwrite.ec"
 int  f_volume    ;
 
#line 126 "sqlwrite.ec"
 int  f_packets    ;
 
#line 127 "sqlwrite.ec"
 char  f_flushed_at [ 30 ]    ;
 
#line 128 "sqlwrite.ec"
 int  ind_flushed_at    ;
 
#line 129 "sqlwrite.ec"
 char  f_lastUpdate [ 30 ]    ;
 
#line 130 "sqlwrite.ec"
 char  f_firstUpdate [ 30 ]    ;
 
#line 131 "sqlwrite.ec"
 const char * f_interface    ;
 
#line 132 "sqlwrite.ec"
 char * f_contents    ;
 
#line 133 "sqlwrite.ec"
 int  ind_contents    ;
 
#line 134 "sqlwrite.ec"
 unsigned char * f_captured_data    ;
 
#line 135 "sqlwrite.ec"
 int  ind_captured_data    ;
/* exec sql end declare section */
#line 136 "sqlwrite.ec"


	f_port_src = cr->port_src_m;
	f_src_ip_serial = cr->srcSerial_m;
	f_port_dst = cr->port_dst_m;
	f_dst_ip_serial = cr->dstSerial_m;
	f_protocol_number = cr->ip_proto_m;
	f_volume = cr->volume_m;
	f_packets = cr->packets_m;
	if (now) {
		timevalToDate(now, f_flushed_at);
		ind_flushed_at = 0;
	} else
		ind_flushed_at = -1;
	timevalToDate(&cr->lastUpdate_, f_lastUpdate);
	timevalToDate(&cr->firstUpdate_, f_firstUpdate);
	f_interface = interfaceName.c_str();
	if (cr->data_.size()) {
		f_captured_data = escBinary((const unsigned char *)cr->data_.c_str(), cr->data_.size());
		ind_captured_data = 0;
	} else {
		ind_captured_data = -1;
	}
	pthread_mutex_lock(&SqlWriteMutex);

	{ ECPGtrans(__LINE__, NULL, "begin transaction ");}
#line 161 "sqlwrite.ec"

	{ ECPGdo(__LINE__, 0, 1, NULL, "insert into connections ( src_ip_serial  , dst_ip_serial  , port_src  , port_dst  , protocol_number  , first_seen  , last_seen  , packets  , volume  , interface  , flushed_at  , captured_data  ) values (  ? ,  ? ,  ? ,  ? ,  ? ,  ? ,  ? ,  ? ,  ? ,  ? ,  ? ,  ? ) ", 
	ECPGt_int,&(f_src_ip_serial),(long)1,(long)1,sizeof(int), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_int,&(f_dst_ip_serial),(long)1,(long)1,sizeof(int), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_int,&(f_port_src),(long)1,(long)1,sizeof(int), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_int,&(f_port_dst),(long)1,(long)1,sizeof(int), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_int,&(f_protocol_number),(long)1,(long)1,sizeof(int), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_char,(f_firstUpdate),(long)30,(long)1,(30)*sizeof(char), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_char,(f_lastUpdate),(long)30,(long)1,(30)*sizeof(char), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_int,&(f_packets),(long)1,(long)1,sizeof(int), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_int,&(f_volume),(long)1,(long)1,sizeof(int), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_char,&(f_interface),(long)0,(long)1,(1)*sizeof(char), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_char,(f_flushed_at),(long)30,(long)1,(30)*sizeof(char), 
	ECPGt_int,&(ind_flushed_at),(long)1,(long)1,sizeof(int), 
	ECPGt_unsigned_char,&(f_captured_data),(long)0,(long)1,(1)*sizeof(char), 
	ECPGt_int,&(ind_captured_data),(long)1,(long)1,sizeof(int), ECPGt_EOIT, ECPGt_EORT);}
#line 175 "sqlwrite.ec"

	
	if (sqlca.sqlcode != 0) {//  && sqlca.sqlerrm.sqlerrml != 69) {
		printf("insert into usage Error %d message '%s' byta '%s'",
					sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc, f_captured_data);
		syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR), "insert into usage Error %d message '%s'",
					sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
		{ ECPGtrans(__LINE__, NULL, "rollback");}
#line 182 "sqlwrite.ec"

		retval = false;
	} else {
		{ ECPGtrans(__LINE__, NULL, "commit");}
#line 185 "sqlwrite.ec"

	}
	
	if (ind_captured_data == 0)
		delete []f_captured_data;
	pthread_mutex_unlock(&SqlWriteMutex);
	return retval;
}

int	SQLGetDNS(string resolvedName, const struct in_addr& ip, const char *mac)
{
	int		retCode= 0;
	/* exec sql begin declare section */
	 	
		
		

	 	
	 	
	 	
			
	
#line 198 "sqlwrite.ec"
 int  f_serial    ;
 
#line 199 "sqlwrite.ec"
 char  f_hostname [ 512 ]    ;
 
#line 200 "sqlwrite.ec"
 char  f_ip_address [ 16 ]    ;
 
#line 202 "sqlwrite.ec"
 const char * q_hostname    ;
 
#line 203 "sqlwrite.ec"
 const char * q_ip_address    ;
 
#line 204 "sqlwrite.ec"
 const char * q_mac    ;
 
#line 205 "sqlwrite.ec"
 int  ind_mac    ;
/* exec sql end declare section */
#line 206 "sqlwrite.ec"

	char	ip_char[inet_to_stringSize];


	q_hostname = resolvedName.c_str();
	inet_to_char(ip, ip_char);
	q_ip_address = ip_char;
	if (mac != NULL) {
		ind_mac = 1;
		q_mac = mac;
	} else {
		ind_mac = -1;
	}

	pthread_mutex_lock(&SqlWriteMutex);
	for (;;) {
		{ ECPGtrans(__LINE__, NULL, "begin transaction ");}
#line 222 "sqlwrite.ec"

		{ ECPGdo(__LINE__, 0, 1, NULL, "select  serial , hostname , ip  from dnsentry where hostname =  ? and ip =  ?  ", 
	ECPGt_char,&(q_hostname),(long)0,(long)1,(1)*sizeof(char), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_char,&(q_ip_address),(long)0,(long)1,(1)*sizeof(char), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
	ECPGt_int,&(f_serial),(long)1,(long)1,sizeof(int), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_char,(f_hostname),(long)512,(long)1,(512)*sizeof(char), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_char,(f_ip_address),(long)16,(long)1,(16)*sizeof(char), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
#line 226 "sqlwrite.ec"

		
		if (sqlca.sqlcode == 0) {
			retCode = f_serial;
			break;
		} else if (sqlca.sqlcode != ECPG_NOT_FOUND) {
			syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_INFO), "select from dnsentry Error %d message '%s' ip '%s' host '%s'",
					sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc, q_ip_address, q_hostname);
			{ ECPGtrans(__LINE__, NULL, "rollback");}
#line 234 "sqlwrite.ec"

			break;
		} else {
			{ ECPGdo(__LINE__, 0, 1, NULL, "insert into dnsentry ( hostname  , ip  , mac  ) values (  ? ,  ? ,  ? ) ", 
	ECPGt_char,&(q_hostname),(long)0,(long)1,(1)*sizeof(char), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_char,&(q_ip_address),(long)0,(long)1,(1)*sizeof(char), 
	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
	ECPGt_char,&(q_mac),(long)0,(long)1,(1)*sizeof(char), 
	ECPGt_int,&(ind_mac),(long)1,(long)1,sizeof(int), ECPGt_EOIT, ECPGt_EORT);}
#line 238 "sqlwrite.ec"


			if (sqlca.sqlcode != 0) {
				syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_INFO), "insert into dnsentry Error %d message '%s'",
						sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
				{ ECPGtrans(__LINE__, NULL, "rollback");}
#line 243 "sqlwrite.ec"

				break;
			}
			// continue on to do select to get serial and return it.
		}
		{ ECPGtrans(__LINE__, NULL, "commit");}
#line 248 "sqlwrite.ec"

	}
	pthread_mutex_unlock(&SqlWriteMutex);
	return retCode;
}

